<?php
namespace imcat;

//cp错误异常类
class glbError extends \Exception {

    private $erCode = 0;
    private $erMsg = '';
    private $erFile = '';
    private $erLine = 0;
    private $erLevel = 0;
    private $trace = array();

    //抛出错误信息，用于外部调用
    static function show($msg="", $code=0, $erFile='', $erLine=0) {
         new self($code, $msg, $erFile, $erLine); 
    }

    function __construct($erCode=0, $erMsg='', $erFile='', $erLine=0) { 
        parent::__construct(); //$erMsg,$erCode
        $this->detail($erCode, $erMsg, $erFile, $erLine);
        $this->dtrace();
        $this->errView();
    }

    //detail
    protected function detail($erCode=0, $erMsg='', $erFile='', $erLine=0) {
        if(is_array($erMsg)){
            $erStr = implode("<br>", $erMsg);
            $this->erMsg = basDebug::hidInfo($erStr, 1); 
            $this->erCode = $erCode;
        }elseif(is_object($erCode)){ 
            $this->erMsg = $erCode->getMessage();
            $this->erFile = $erCode->getFile();
            $this->erLine = $erCode->getLine();
            //$this->trace = $erCode;
            $this->erCode = -24;
        }elseif(!empty($erFile)){
            $this->erMsg = $erMsg;
            $this->erCode = $erCode;
            $this->erFile = $erFile;
            $this->erLine = $erLine;
        }elseif(!empty($erMsg)){
            $this->erMsg = $erMsg; 
            $this->erCode = $erCode;
        }else{ 
            $err = error_get_last(); 
            if(!empty($err)){
                $this->erMsg = $err['message']; 
                $this->erFile = $err['file'];
                $this->erLine = $err['line'];
                $this->erCode = $err['type'];
            }
        }
    }
    
    //获取trace信息
    protected function dtrace() { 
        $trace = empty($this->trace) ? $this->getTrace() : $this->trace;
        $tInfo = [];
        foreach($trace as $t) {
            $class = isset($t['class']) ? $t['class'] : '';
            $type = isset($t['type']) ? $t['type'] : '';
            $function = isset($t['function']) ? $t['function'] : '';
            $tInfo[] = @$t['file'] . ' (' . @$t['line'] . ') ' . $class . $type . $function;
        }
        $this->trace = $tInfo;
    }

    // 输出错误信息
    protected function errView(){
        global $_cbase;

        // sLevel,message,title,traceInfo:为兼容旧模板
        $erCode = $sLevel = empty($this->erCode) ? '[RUN]' : (is_numeric($this->erCode) ? $this->getLevel() : $this->erCode);
        $erMsg = $message = $title = basDebug::hidInfo($this->erMsg);
        $erFile = $this->erFile;
        $erLine = $this->erLine;
        $erTrace = basDebug::hidInfo($this->trace);
        $traceInfo = implode("<br>",basDebug::hidInfo($this->trace)); // 兼容

        // 
        if(basEnv::isMpro() || basEnv::isAjax() || defined('RUN_AJAX')){
            $data = ['errno'=>$erCode, 'errmsg'=>$erMsg, 'erFile'=>$erFile, 'erLine'=>$erLine, 'erTrace'=>$erTrace];
            vopApi::view($data);
        }else{
            glbHtml::httpStatus('404');
            include vopTpls::cinc("base:stpl/err_info");
        }
        if(!defined('ERR_NODIE')){
            die(); // ??? 
        }
        /*
            ob_start(); 
            include vopTpls::cinc("base:stpl/err_ajax");
            $re = ob_get_contents(); 
            $re = strip_tags($re,'<li>');
            $re = str_replace(array('<li>','</li>'),array("  - ",""),$re);
            ob_clean();
        */
    }
    
    //错误等级
    protected function getLevel() {
       $arr = array(    
            1=> '(E_ERROR)',
            2 => '(E_WARNING)',
            4 => '(E_PARSE)',  
            8 => '(E_NOTICE)',  
            16 => 'E_CORE_ERROR',  
            32 => 'E_CORE_WARNING',  
            64 => '(E_COMPILE_ERROR)', 
            128 => '(E_COMPILE_WARNING)',  
            256 => '(E_USER_ERROR)',  
            512 => '(E_USER_WARNING)', 
            1024 => '(E_USER_NOTICE)',  
            2047 => 'E_ALL', 
            2048 => 'E_STRICT',
            '-24' => 'EXCEPT_HANDLER',
        );
        $fix = isset($arr[$this->erCode]) ? "({$arr[$this->erCode]})" : '';
        return $this->erCode.$fix;
    }

}